package main

import (
	"fmt"
	"gitlab.w2gou.cn/golib/filemap"
	"gitlab.w2gou.cn/xbc/go-lib/interval"
	"gitlab.w2gou.cn/xbc/go-lib/log"
	"gitlab.w2gou.cn/xbc/go-lib/util"
	"os"
	"time"
)

/*
filemap 测试
*/
func testFileMapRead() {
	obj := filemap.New("speed", 1024*1024*1024)

	r := obj.Find("0000000013")
	log.Info4("", "read", "r", string(r))
}

/*
写的速度，用了缓存后，顺序key、随机的区别就不大了
1w个顺序key 220ms
1w个随机key 203ms
*/
func testFileMapSpeed() {
	obj := filemap.New("speed", 1024*1024*1024)
	obj.Clear()

	keys := make([]string, 0)

	for i := 0; i < 100; i += 1 {
		k := fmt.Sprintf("%010d", i)
		keys = append(keys, k)

		if i == 13 {
			fmt.Println(k)
		}
	}
	//keys = util.ReadFileLines("rand2.txt")

	t1 := time.Now()
	for _, k := range keys {
		obj.Insert(k, []byte(k+k), 0)
	}
	t2 := time.Now()

	obj.DumpPng("big.txt")
	log.Info4("test", "性能测试", "sub", t2.Sub(t1))
}

/*
检查filemap二叉树的正确性
*/
func testFileMapSame() {

	for i := 0; ; i += 1 {
		testFmOne(i)

		time.Sleep(time.Second)
	}
}

func testFmOne(count int) {
	keys, dels := genRandStr()

	t2 := filemap.New("testRbtree1", 10000)
	t2.Clear()

	t1 := NewTree()
	for _, key := range keys {
		t1.Insert(key, 0)
		t2.Insert(key, []byte(" "), 0)
	}

	checkSame(t1, t2, keys, dels, 1)

	for i, d := range dels {
		k := keys[d]

		t1.Delete(k)
		t2.Delete(k)

		checkSame(t1, t2, keys, dels, 10000+i)
	}
	//t2.DumpPng("test.txt")

	log.Info4("test", "测试通过", "count", count, "keys", len(keys), "dels", len(dels))

}

var incr = 1
var gitl = interval.NewInterval()

func checkSame(t1 *Tree, t2 *filemap.Map, keys []string, dels []int, tag int) bool {
	d1 := t1.DumpKey()
	d2 := t2.DumpKey()

	if d1 != d2 {
		t1.DumpPng(fmt.Sprintf("t1-%v.txt", incr))
		t2.DumpPng(fmt.Sprintf("t2-%v.txt", incr))

		incr += 1

		log.Info4("err", "发现不同", "tag", tag, "keys", util.Json(keys), "dels", util.Json(dels),
			"d1", d1, "d2", d2)

		log.WriteAll()
		os.Exit(1)
		return false
	}
	ik := "write one"
	if gitl.IsTimeover(ik, 60) {
		gitl.Set(ik)

		log.Info4("test", "dump str", "d2", d2)
		t2.DumpPng("d2.txt")
	}
	return true
}

//generator
/*

@return (随机字符串数据, 要删除的index)
*/
func genRandStr() ([]string, []int) {
	ss := make([]string, 0)
	size := util.RandRange(10, 100)

	for i := 0; i < size; i += 1 {
		ss = append(ss, util.RandFakerString(5))
	}

	// 要删的个数在 1/3 和 2/3 之间
	delCount := util.RandRange(size/3, 2*size/3)
	mp := make(map[int]bool)
	for i := 0; i < delCount; i += 1 {
		r := util.RandRange(0, size-1)
		mp[r] = true
	}
	dels := make([]int, 0)
	for v := range mp {
		dels = append(dels, v)
	}

	return ss, dels
}
